package com.mr.util;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
/**
 * @author <a href="mailto:acerge@163.com">gebiao(acerge)</a>
 * @since 2007-9-28 02:05:17
 */
public class DateUtil {
   private static final String defaultDatePattern = "yyyy-MM-dd";
   private static final String timePattern = "HH:mm:ss";
   private static final SimpleDateFormat fullTimeFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
   private static final SimpleDateFormat onlyDateFormat=new SimpleDateFormat("yyyy-MM-dd");
   public static final long m_second=1000;
   public static final long m_minute=m_second*60;
   public static final long m_hour=m_minute*60;
   public static final long m_day=m_hour*24;
   /**
   * <p>DateUtil instances should NOT be constructed in standard programming.</p>
   *
   * <p>This constructor is public to permit tools that require a JavaBean instance
   * to operate.</p>
    */
   public DateUtil(){}
   /**
    * @return current time
    */
   public static final Date currentTime(){
      return new Date();
   }
   public static final int nextMonth(){
	  String next = format(new Date(), "M");
	  int nextMonth = Integer.parseInt(next) + 1;
	  if(nextMonth==13) return 1;
	  return nextMonth;
   }
   /**
    * parse date using default pattern yyyy-MM-dd
    * @param strDate
    * @return
    * @throws ParseException
    */
   public static final Date parseDate(String strDate){
      Date date = null;
      try {
         date = onlyDateFormat.parse(strDate);
         return date;
      } catch (Exception pe) {
      	return null;
      }
   }
   public static final Timestamp parseTimestamp(String strDate){
      try {
         Timestamp result = Timestamp.valueOf(strDate);
         return result;
      } catch (Exception pe) {
      	return null;
      }
   }

   /**
    * @param strDate
    * @param pattern
    * @return
    * @throws ParseException
    */
   public static final Date parseDate(String strDate, String pattern){
      SimpleDateFormat df = null;
      Date date = null;
      df = new SimpleDateFormat(pattern);
      try {
         date = df.parse(strDate);
         return date;
      } catch (Exception pe) {
         return null;
      }
   }

   /**
    * @param aDate
    * @return formated date by yyyy-MM-dd
    */
   public static final String formatDate(Date date) {
   	if(date==null) return null;
      return format(date, defaultDatePattern);
   }

   /**
    * @param aDate
    * @return formated time by HH:mm:ss
    */
   public static final String formatTime(Date date) {
   	if(date==null) return null;
      return format(date, timePattern);
   }

   /**
    * @param aDate
    * @return formated time by yyyy-MM-dd HH:mm:ss
    */
   public static final String formatTimestamp(Date date) {
   	if(date==null) return null;
      return fullTimeFormat.format(date);
   }

   /**
    * @param aDate
    * @param pattern: Date format pattern
    * @return
    */
   public static final String format(Date aDate, String pattern) {
   	if(aDate==null) return null;
   	SimpleDateFormat df = null;
      String returnValue = "";
      if (aDate == null)
         return null;
      df = new SimpleDateFormat(pattern);
      returnValue = df.format(aDate);
      return (returnValue);
   }

   /**
    * @param original
    * @param days
    * @param hours
    * @param minutes
    * @param seconds
    * @param mill
    * @return original+day+hour+minutes+seconds+millseconds
    */
   public static final <T extends Date> T addTime(T original,int days, int hours, int minutes, int seconds, int mill){
   	if(original==null) return null;
      long newTime=original.getTime()+m_day*days+m_hour*hours+m_minute*minutes+m_second*seconds;
      T another = (T) original.clone();
      another.setTime(newTime);
      return another;
   }
   public static final <T extends Date> T addDay(T original,int days){
   	if(original==null) return null;
      long newTime=original.getTime()+m_day*days;
      T another = (T) original.clone();
      another.setTime(newTime);
      return another;
   }
   public static final <T extends Date> T addHour(T original, int hours){
   	if(original==null) return null;
      long newTime=original.getTime()+m_hour*hours;
      T another = (T) original.clone();
      another.setTime(newTime);
      return another;
   }
   public static final <T extends Date> T addMinute(T original, int minutes){
   	if(original==null) return null;
      long newTime=original.getTime() + m_minute*minutes;
      T another = (T) original.clone();
      another.setTime(newTime);
      return another;
   }
   
   /**
    * @param day
    * @return for example ,1997/01/02 22:03:00,return 1997/01/02 00:00:00.0
    */
   public static final <T extends Date> T getBeginningTimeOfDay(T day){
   	if(day==null) return null;
      //new Date(0)=Thu Jan 01 08:00:00 CST 1970
      Long mill = day.getTime();
      if((mill + m_hour*8) % m_day !=0) mill = mill - mill % m_day - m_hour * 8;
      T another = (T) day.clone();
      another.setTime(mill);
      return another;
   }
   /**
    * @param day
    * @return for example ,1997/01/02 22:03:00,return 1997/01/03 23:59:59.999
    */
   public static final <T extends Date> T getLastTimeOfDay(T day){
   	if(day==null) return null;
      Long mill = getBeginningTimeOfDay(day).getTime() + m_day - 1;
      T another = (T) day.clone();
      another.setTime(mill);
      return another;
   }
   /**
    * 09:00:00,09:07:00 ---> 9:00,9:7:00
    * @param time
    * @return
    */
   public static final String formatTime(String time){
   	if(time==null) return null;
      time = StringUtils.trim(time);
      if(StringUtils.isBlank(time)) throw new IllegalArgumentException("时间格式有错误！");
      time = time.replace('：', ':');
      String[] times = time.split(":");
      String result="";
      if(times[0].length()<2) result += "0" + times[0]+":";
      else result += times[0]+":";
      if(times.length > 1){
         if(times[1].length()<2) result += "0" + times[1];
         else result += times[1];
      }else{
         result += "00";
      }
      java.sql.Timestamp.valueOf("2001-01-01 " + result + ":00");
      return result;
   }
	public static boolean isTomorrow(Date date) {
   	if(date==null) return false;
		if(formatDate(addTime(new Date(), 1, 0, 0, 0, 0)).equals(formatDate(date))) return true;
		return false;
	}
   /***
    * @param date
    * @return 1,2,3,4,5,6,7
    */
   private static int[] chweek = new int[]{0,7,1,2,3,4,5,6};
   public static Integer getWeek(Date date) {
   	if(date==null) return null;
      Calendar c = Calendar.getInstance();
      c.setTime(date);
      return chweek[c.get(Calendar.DAY_OF_WEEK)];
   }
   private static String[] cnweek = new String[]{"", "周日", "周一", "周二", "周三", "周四", "周五", "周六"};
   public static String getCnWeek(Date date){
   	if(date==null) return null;
      Calendar c = Calendar.getInstance();
      c.setTime(date);
      return cnweek[c.get(Calendar.DAY_OF_WEEK)];
   }
	public static Integer getMonth(Date date) {
		if(date==null) return null;
		String month = format(date, "M");
		return Integer.parseInt(month);
	}
	public static Integer getCurrentDay(){
		return getDay(new Date());
	}
	public static Integer getCurrentMonth(){
		return getMonth(new Date());
	}
   public static Integer getCurrentYear() {
      return getYear(new Date());
   }
   public static Integer getYear(Date date) {
   	if(date==null) return null;
      String year = DateUtil.format(date, "yyyy");
      return Integer.parseInt(year);
   }
   public static Integer getDay(Date date) {
   	if(date==null) return null;
      String year = DateUtil.format(date, "d");
      return Integer.parseInt(year);
   }
   public static String getCurDateStr(){
   	return DateUtil.formatDate(new Date());
   }
   public boolean isAfter(Date date){
   	if(date.after(new Date())){
   		return true;
   	}
   	return false;
   }
	/**
	 * 获取date所在月份的星期为weektype且日期在date之后（或等于）的所有日期
	 * @param weektype
	 * @return
	 */
	public static List<Date> getWeekDateList(Date date, String weektype) {
		int curMonth = getMonth(date);
		int week = Integer.parseInt(weektype);
		int curWeek = getWeek(date);
		int sub = (7 + week - curWeek) % 7;
		Date next = addDay(date, sub);
		List<Date> result = new ArrayList<Date>();
		while(getMonth(next) == curMonth){
			result.add(next);
			next = addDay(next, 7);
		}
		return result;
   }
	/**
	 * 获取date之后(包括date)的num个星期为weektype日期（不限制月份）
	 * @param weektype
	 * @return
	 */
	public static List<Date> getWeekDateList(Date date, String weektype, int num) {
		int week = Integer.parseInt(weektype);
		int curWeek = getWeek(date);
		List<Date> result = new ArrayList<Date>();
		int sub = (7 + week - curWeek) % 7;
		Date next = addDay(date, sub);
		for(int i=0; i<num; i++){
			result.add(next);
			next = addDay(next, 7);
		}
		return result;
   }
	public static Date getCurDate(){
		return getBeginningTimeOfDay(new Date());
	}
	public static String formatCurDate(String pattern){
		return format(getCurDate(), pattern);
	}
	public static String getCnCurWeek(){
		return getCnWeek(getCurDate());
	}
	/**
	 * 获取日期所在月份的第一天
	 * @param date
	 * @return
	 */
	public static Date getMonthFirstDay(Date date) {
		String dateStr = format(date, "yyyy-MM") + "-01";
		return parseDate(dateStr);
   }
	public static String formatDate(int days){
		return formatDate(addDay(new Date(), days));
	}
	public static Timestamp getCurTimestamp() {
		return new Timestamp(System.currentTimeMillis());
	}
	public static Integer getHour(Date date) {
		if(date==null) return null;
		String hour = format(date, "H");
		return Integer.parseInt(hour);
	}
	
	public static void main(String[] args){
		System.out.println(getHour(new Date())< 20);
	}
	
}
